package com.sunxd.zstudy.juc.T20_ThreadPool.threadPool;

import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

/**
 * 对多个线程对处理和对执行结果的处理，支持传入线程池
 *
 * 用法
 * CompletableFuture.runAsync() 执行Runnable 接口，且没有返回值
 * CompletableFuture.supplyAsync() 可执行Callable 、Runnable 接口，带返回值
 * whenComplete 执行结果（有异常也不会往外抛出）
 * exceptionally 执行报错
 * thenCombine 合并任务
 * thenApply ——拿到第一个执行的结果 执行下一个 将2个线程串行化
 * handle 对执行结果的计算
 * thenAccept 消费处理结果
 * thenRun 同 thenAccept 区别并不会把上个执行结果当参数传递进来——— 功能同thenApply
 * thenCombine 合并任务  带返回值
 * thenAcceptBoth 合并任务 不带返回值
 * applyToEither 哪个执行带快用哪个 带返回值
 * acceptEither  哪个执行带快用哪个  不带返回值
 * runAfterEither  有一个执行完就可以
 * runAfterBoth  两个都执行完才行
 * thenCompose  方法允许你对两个 CompletionStage 进行流水线操作，第一个操作完成时，将其结果作为参数传递给第二个操作。
 *
 *
 * @author: 作者名称sdfSDFs'd'fad
 * @date: 2021-09-14 21:43
 **/
public class T4_CompletableFuture {

    public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {



        // 不能带返回值
//        long start = System.currentTimeMillis();
//        System.out.println("start");
//        CompletableFuture<Void> futureTM = CompletableFuture.runAsync(()->{System.out.println("TM run"); delay();});
//        CompletableFuture<Void> futureTB = CompletableFuture.runAsync(()->{ System.out.println("TB run "); delay();});
//        CompletableFuture<Void> futureJD = CompletableFuture.runAsync(()->{ System.out.println("JD run "); delay();});
//        CompletableFuture.allOf(futureJD,futureTB,futureTM).join();
//        CompletableFuture.anyOf(futureJD,futureTB,futureTM).join();
//        long end = System.currentTimeMillis();
//        System.out.println(end -start);
//        System.out.println("end");



//************************—————————————supplyAsync——————————————————————————--——————————
        // 异步处理 带返回值
//        long start = System.currentTimeMillis();
//        System.out.println("start");
//        CompletableFuture<String> futureTM = CompletableFuture.supplyAsync(()->{System.out.println("TM run"); delay(); return "TM";});
//        CompletableFuture<String> futureTB = CompletableFuture.supplyAsync(()->{ System.out.println("TB run "); delay(); return "TB";});
//        CompletableFuture<String> futureJD = CompletableFuture.supplyAsync(()->{ System.out.println("JD run "); delay(); return "JD";});
//        CompletableFuture.allOf(futureJD,futureTB,futureTM).join();
//        CompletableFuture.anyOf(futureJD,futureTB,futureTM).join();
//        long end = System.currentTimeMillis();
//        System.out.println(end -start);
//        System.out.println("end");

//************************—————————————自定义线程池 executorService——————————————————————————--——————————
        // 可指定（自定义）执行工厂 ，不知定则使用默认的
//        ExecutorService executorService = new ThreadPoolExecutor(2, 4,
//                60, TimeUnit.SECONDS,
//                new ArrayBlockingQueue<Runnable>(4),
//                Executors.defaultThreadFactory(),
//                new ThreadPoolExecutor.AbortPolicy());
//        CompletableFuture<Void> futureTM = CompletableFuture.runAsync(()->{System.out.println("TM run" + Thread.currentThread().getName()); delay();},executorService);
//        CompletableFuture.allOf(futureTM);
//        System.out.println("out:"+futureTM.get());

//************************—————————————whenComplete ———————exceptionally——————————————————————————--——————————
        // 包含异常，即使里面有异常，也不会往外跑出
//        whenComplete（whenCompleteAsync 异步） 执行完后执行的动作。exceptionally 发生异常执行的动作
//        CompletableFuture<String> futureTM = CompletableFuture.supplyAsync(()->{System.out.println("TM run"); delay(); return "TM";});
//        futureTM.whenComplete((s, throwable) -> {
//            System.out.println("print s:" + s);
//            System.out.println("print error:" + throwable.getMessage());
//        });
//
//        futureTM.exceptionally(new Function<Throwable, String>() {
//            @Override
//            public String apply(Throwable throwable) {
//                System.out.println("执行失败！"+throwable.getMessage());
//                return null;
//            }
//        });

//************************————————————thenApply——拿到第一个执行的结果 执行下一个 将2个线程串行化———————————————————————--——————————
//        CompletableFuture<String> futureTM = CompletableFuture.supplyAsync(()->{System.out.println("TM run"); delay(); return "TM";});
//        CompletableFuture<String> futureTM1 =futureTM.thenApply(new Function<String, String>() {
//            @Override
//            public String apply(String s) {
//                System.out.println("in s="+s);
//                return s+"thenApply";
//            }
//        });
//        System.out.println(futureTM1.get());


//************************————————————handle对执行结果的计算———————————————————————--—————
//        CompletableFuture<String> futureTM = CompletableFuture.supplyAsync(()->{System.out.println("TM run"); delay(); return "TM";});
//        CompletableFuture<String> handle =   futureTM.handle(new BiFunction<String, Throwable, String>() {
//            @Override
//            public String apply(String s, Throwable throwable) {
//                return " first handle : "+s ;
//            }
//        }).handle(new BiFunction<String, Throwable, String>() {
//
//            @Override
//            public String apply(String s, Throwable throwable) {
//                return " second handle : "+s ;
//            }
//        });
//        System.out.println(handle.get());


//************************—————————thenAccept 消费处理结果———————————————————————--—————
//        CompletableFuture<String> futureTM = CompletableFuture.supplyAsync(()->{System.out.println("TM run"); delay(); return "TM";});
//        futureTM.thenAccept(new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                System.out.println("thenAccept:"+s);
//            }
//        });
//        System.out.println(futureTM.get());



// ************************—————————thenRun 同 thenAccept 区别并不会把上个执行结果当参数传递进来——— 功能同thenApply————————————————————--—————
//        CompletableFuture<String> futureTM = CompletableFuture.supplyAsync(()->{System.out.println("TM run"); delay(); return "TM";});
//        futureTM.thenRun(new Runnable() {
//            @Override
//            public void run() {
//                System.out.println("then run ..... 可用于无关的线程");
//            }
//        });
//        System.out.println(futureTM.get());


// ************************—————————thenCombine 合并任务————————————————————--—————
//        CompletableFuture<String> futureTM = CompletableFuture.supplyAsync(()->{ delay(); return "TM";});
//        CompletableFuture<String> futureTB = CompletableFuture.supplyAsync(()->{ delay(); return "TB";});
//        CompletableFuture<String> objectCompletableFuture = futureTM.thenCombine(futureTB, new BiFunction<String, String, String>() {
//            @Override
//            public String apply(String s, String s2) {
//                return "combine :" + s + "-" + s2;
//            }
//        });
//        System.out.println(objectCompletableFuture.get());

// ************************—————————thenAcceptBoth thenCombine无返回值 合并任务————————————————————--—————
//        CompletableFuture<String> futureTM = CompletableFuture.supplyAsync(()->{ delay(); return "TM";});
//        CompletableFuture<String> futureTB = CompletableFuture.supplyAsync(()->{ delay(); return "TB";});
//        CompletableFuture<Void> objectCompletableFuture = futureTM.thenAcceptBoth(futureTB, new BiConsumer<String, String>() {
//            @Override
//            public void accept(String s, String s2) {
//                System.out.println("accept :" + s + "-" + s2);
//            }
//        });
//        System.out.println(objectCompletableFuture.get());


// ************************—————————applyToEither 哪个执行带快用哪个————————————————————--—————
//        CompletableFuture<String> futureTM = CompletableFuture.supplyAsync(()->{ delay(); return "TM";});
//        CompletableFuture<String> futureTB = CompletableFuture.supplyAsync(()->{ delay1(); return "TB";});
//        CompletableFuture<String> objectCompletableFuture = futureTM.applyToEither(futureTB, new Function<String, String>() {
//            @Override
//            public String apply(String s) {
//                return s;
//            }
//        });
//        System.out.println(objectCompletableFuture.get());


// ************************—————————acceptEither 哪个执行带快用哪个————————————————————--—————
        CompletableFuture<String> futureTM = CompletableFuture.supplyAsync(()->{ delay(); return "TM";});
        CompletableFuture<String> futureTB = CompletableFuture.supplyAsync(()->{ delay1(); return "TB";});
        futureTM.acceptEither(futureTB, new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });





        System.in.read();
    }

    public static void delay(){
        try {
            TimeUnit.SECONDS.sleep(6);
//            throw new RuntimeException();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void delay1(){
        try {
            TimeUnit.SECONDS.sleep(2);
//            throw new RuntimeException();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}
